package com.bianmaba.wdc.service;

import com.bianmaba.spring.supports.data.repository.specification.condition.predicate.PredicateGeneratorFactory;
import com.bianmaba.wdc.bean.entity.Holiday;
import com.bianmaba.wdc.bean.entity.SpecialWeekday;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class WeekdayCalculationService {
    @Autowired
    private IHolidayService holidayService;
    @Autowired
    private ISpecialWeekdayService specialWeekdayService;

    public List<Holiday> getHolidays(Date start, Date end) {
        List<Holiday> holidays = holidayService.getRepository().findAll(new Specification<Holiday>() {
            @Override
            public Predicate toPredicate(Root<Holiday> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate st = cb.between(root.get("startDate"), start, end);
                Predicate et = cb.between(root.get("endDate"), start, end);
                return cb.or(st, et);
            }
        });
        return holidays;
    }

    public List<SpecialWeekday> getSpecialWeekdays(Date start, Date end) {
        List<SpecialWeekday> holidays = specialWeekdayService.getRepository().findAll(new Specification<SpecialWeekday>() {
            @Override
            public Predicate toPredicate(Root<SpecialWeekday> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate st = cb.between(root.get("dt"), start, end);
                Predicate et = cb.between(root.get("dt"), start, end);
                return cb.or(st, et);
            }
        });
        return holidays;
    }

    public int calculate(Date start, Date end) {
        int result = 0;
        Date targetStart = start;
        Date targetEnd = DateUtils.addDays(end, 1);
        List<Holiday> holidays = getHolidays(targetStart, targetEnd);
        List<SpecialWeekday> specialWeekdays = getSpecialWeekdays(targetStart, targetEnd);
        while (targetStart.getTime() < targetEnd.getTime()) {
            Calendar calendar = DateUtils.toCalendar(targetStart);
            //判断日期是否是周六周日
            if (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
                //判断日期是否是节假日
                if (!isHoliday(holidays, targetStart)) {
                    result++;
                }
            } else {
                //如果是周6周日，则再判断是否是补班
                if (isSpecialWeekday(specialWeekdays, targetStart)) {
                    result++;
                }
            }

            targetStart = DateUtils.addDays(targetStart, 1);
        }
        return result;
    }

    private boolean isSpecialWeekday(List<SpecialWeekday> specialWeekdays, Date targetDay) {
        for (SpecialWeekday item : specialWeekdays) {
            if (item.getDt().getTime() == targetDay.getTime()) {
                return true;
            }
        }
        return false;
    }

    public boolean isHoliday(List<Holiday> holidays, Date targetDay) {
        for (Holiday item : holidays) {

            if (item.getStartDate().getTime() <= targetDay.getTime() && item.getEndDate().getTime() >= targetDay.getTime()) {
                return true;
            }
        }
        return false;
    }
}
